/**
 * Copyright 2010 The Regents of the University of California
 *
 *  All Rights Reserved
 */
#ifndef _FLOW_INSERTION_H
#define _FLOW_INSERTION_H

#include "rconn.h"
#include "learning-switch.h"
#include "openflow/openflow.h"
#include "lib/new-switch-handler.h"

bool create_upward_flow_entry(struct rconn* rconn, struct lswitch *sw, struct flow* flow, struct ofp_packet_in* opi);
void init_switch_prefixes(int sw_index, struct lswitch* sw, struct rconn* rconn);
void insert_PIP_entry(struct rconn* rconn, struct lswitch* sw, uint8_t *dstPMAC, uint16_t port);
void delete_L2_entry(struct rconn* rconn, struct lswitch* sw);
void process_flow(struct lswitch *sw, struct rconn *local, const struct ofp_flow_stats *fs);
void insert_L2_entry(struct rconn* rconn, struct lswitch* sw, uint8_t *dstPMAC, uint16_t port);
void modify_L2_entry(struct rconn* rconn, struct lswitch* sw, uint8_t *dstPMAC, uint16_t port, uint16_t orig_output_port, const struct ofp_flow_stats *fs);
void insert_modify_L2_entry(struct rconn* rconn, struct lswitch* sw, uint8_t* dstAMAC, uint8_t *dstPMAC, uint16_t port);
void insert_modify_L3_entry(struct rconn* rconn, struct lswitch* sw, uint32_t dstAIP, uint32_t dstPIP , uint16_t port);
void insert_L3_entry(struct rconn* rconn, struct lswitch* sw, uint32_t dstPIP, uint16_t port);
void deleteFlowEntries(struct rconn* rconn, struct lswitch* sw, uint8_t *dstPMAC);
void modifyFlowEntry(struct rconn* rconn, struct lswitch* sw, uint8_t *dstPMAC, uint16_t port);
uint32_t convert_to_uint_ip(uint8_t *dstMAC);
void match_nw_dst(struct rconn* rconn, struct lswitch* sw, uint32_t nw_dst); 
void deleteFlowEntriesPIP(struct rconn* rconn, struct lswitch* sw, uint32_t PIP);
location extractLocationFromIP(uint32_t pip);
void send_flow_stats_request(struct rconn* rconn, struct lswitch* sw, uint16_t port_no);
void modifyFlowEntryPIPEdge(struct rconn* rconn, struct lswitch* sw, uint32_t AIP, uint32_t PIP, uint16_t port);
void modifyFlowEntryPIP(struct rconn* rconn, struct lswitch* sw, uint32_t PIP, uint16_t port);
#endif
